﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConjureBivouac2012.GameStates;
using ConjureBivouac2012.Mathematics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;

namespace ConjureBivouac2012.Object
{
    public class Boss : AbstractEnemy
    {
        bool newBulletNeeded = false;
        private float fireDelay;
        private double lastShootFired;

        public Boss(float fireDelay, double lastShootFired) : base(160, 5)
        {
            this.fireDelay = fireDelay;
            this.lastShootFired = lastShootFired;
        }

        // Return a new bullet that has been shoteed
        public override Entity[] addingEntity()
        {
            if (newBulletNeeded)
            {
                if (random.Next(2) == 1)
                {
                    BossBullet[] bullets = new BossBullet[1];
                    newBulletNeeded = false;

                    for (int i = 0; i < 1; i++)
                    {
                        BossBullet b = new BossBullet();
                        bullets[i] = b;
                    }

                    bullets[0].Fire(this, new Vector2(Direction.X, Direction.Y));
                    return bullets;
                }
                else
                {
                    MonsterD[] bullets = new MonsterD[1];
                    newBulletNeeded = false;

                    for (int i = 0; i < 1; i++)
                    {
                        bullets[i] = new MonsterD(1, -1);

                        Vector2 pos = GetSpawnPosition(bullets[i].GetRadius());

                        if (pos.X != 0 && pos.Y != 0)
                        {
                            bullets[i].sprite.Position = pos;
                            bullets[i].SetDirection(this.GetDirection());
                            bullets[i].setVelocity(new Vector2(80, 80));
                        }
                        else
                        {
                            return null;
                        }
                    }
                    return bullets;
                }
            }
            else
            {
                return null;
            }
        }

        Vector2[] dirs = new Vector2[] { new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0), new Vector2(1, -1),
            new Vector2(0, -1), new Vector2(-1, -1), new Vector2(-1, 0), new Vector2(-1, 1)};

        private Vector2 GetSpawnPosition(float radius)
        {
            List<Entity> list = ((PlayGame) Program.GetGameInstance.GetCurrentState()).GetEntityList();
            Vector2 pos = this.sprite.Position + dirs[random.Next(8)] * (this.GetRadius() + radius + 5);

            bool correct = Phasik.IsPositionWithinBounds(pos, radius) && Phasik.IsCollidesWithAEntity(list, pos, radius);

            if(correct)
            {
                return pos;
            }

            foreach (Vector2 dir in dirs)
            {
                pos = this.sprite.Position + dir * (this.GetRadius() + radius + 5);
                correct = Phasik.IsPositionWithinBounds(pos, radius) && Phasik.IsCollidesWithAEntity(list, pos, radius);

                if(correct)
                {
                    return pos;
                }
            }

            return Vector2.Zero;
        }

        public override void LoadContent(ContentManager contentManager)
        {
            contentName = "Ennemy/MegaBoss";
            this.sprite.LoadContent(contentManager, contentName);
            base.LoadContent(contentManager);
        }

        public override void Update(GameTime time)
        {
            base.Update(time);
            Fire(time);
        }

        public void Fire(GameTime time)
        {
            if (fireDelay > 0 && (lastShootFired == -1 || time.TotalGameTime.TotalSeconds - lastShootFired >= fireDelay))
            {
                lastShootFired = time.TotalGameTime.TotalSeconds;
                newBulletNeeded = true;
            }
        }

        private Vector2 GetFireDirection()
        {
            Vector2 direction = new Vector2(0, 0);

            IGlobalGameState state = Program.GetGameInstance.GetCurrentState();

            AbstractPlayer p = null;

            if (state is PlayGame)
            {
                p = ((PlayGame)state).GetPlayer();
            }

            if (p != null)
            {
                direction = p.GetVehicule().sprite.Position - this.sprite.Position;
                direction.Normalize();
            }

            return direction;
        }
    }
}
